package cn.iocoder.yudao.module.shop.category.dao;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.business.basic.dao.mapper.CoreMapper;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreLambdaQueryWrapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.shop.category.pojo.bo.ShopCategoryCodeBO;
import cn.iocoder.yudao.module.shop.category.pojo.po.ShopCategory;
import cn.iocoder.yudao.module.shop.category.pojo.vo.ShopCategoryListReqVO;
import cn.iocoder.yudao.module.shop.category.pojo.vo.ShopCategoryPageReqVO;
import jakarta.annotation.Nullable;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * 行业类目 Mapper
 *
 * @author 山野羡民（1032694760@qq.com）
 */
@Mapper
public interface ShopCategoryMapper extends CoreMapper<ShopCategory> {

    default PageResult<ShopCategory> selectPage(ShopCategoryPageReqVO reqVO) {
        return selectPage(reqVO, new CoreLambdaQueryWrapper<ShopCategory>()
                .likeIfPresent(ShopCategory::getName, reqVO.getName())
                .eqIfPresent(ShopCategory::getParentId, reqVO.getParentId())
                .inIfPresent(ShopCategory::getId, reqVO.getParentIds())
                .eqIfPresent(ShopCategory::getStatus, reqVO.getStatus())
                .eqIfPresent(ShopCategory::getRecommend, reqVO.getRecommend())
                .orderByDesc(ShopCategory::getRecommend)
                .orderByAsc(ShopCategory::getSort)
                .orderByDesc(ShopCategory::getId));
    }

    default List<ShopCategory> selectAll() {
        return selectList(new CoreLambdaQueryWrapper<ShopCategory>()
                .orderByDesc(ShopCategory::getRecommend)
                .orderByAsc(ShopCategory::getSort)
                .orderByDesc(ShopCategory::getId));
    }

    default List<ShopCategory> selectList(ShopCategoryListReqVO listReqVO) {
        return selectList(new CoreLambdaQueryWrapper<ShopCategory>()
                .likeIfPresent(ShopCategory::getName, listReqVO.getName())
                .eqIfPresent(ShopCategory::getParentId, listReqVO.getParentId())
                .inIfPresent(ShopCategory::getParentId, listReqVO.getParentIds())
                .eqIfPresent(ShopCategory::getStatus, listReqVO.getStatus())
                .eqIfPresent(ShopCategory::getRecommend, listReqVO.getRecommend())
                .orderByDesc(ShopCategory::getRecommend)
                .orderByAsc(ShopCategory::getSort)
                .orderByDesc(ShopCategory::getId));
    }

    @Select("""
            SELECT b.* FROM shop_category AS a, shop_category AS b
            WHERE a.CODE = #{parentCode} AND b.parent_id = a.id AND b.status = 0 AND b.deleted = FALSE
            ORDER BY recommend DESC, sort, id DESC
            """)
    List<ShopCategory> selectEnableSonsByParentCode(@Param("parentCode") String parentCode);

    default Long selectCountByParentId(Long parentId) {
        return selectCount(ShopCategory::getParentId, parentId);
    }

    default List<ShopCategory> selectListByStatus(@Nullable Long parentId, Integer status) {
        return selectList(new CoreLambdaQueryWrapper<ShopCategory>()
                .eqIfPresent(ShopCategory::getParentId, parentId)
                .eqIfPresent(ShopCategory::getStatus, status)
                .orderByDesc(ShopCategory::getRecommend)
                .orderByAsc(ShopCategory::getSort));
    }

    default List<ShopCategory> selectListByParentIdsAndStatus(Collection<Long> parentIds, Integer status) {
        parentIds.removeIf(id -> id == null || id <= 0);
        return selectList(new CoreLambdaQueryWrapper<ShopCategory>()
                .inIfPresent(ShopCategory::getParentId, parentIds)
                .eqIfPresent(ShopCategory::getStatus, status)
                .orderByDesc(ShopCategory::getRecommend)
                .orderByAsc(ShopCategory::getSort)
                .orderByDesc(ShopCategory::getId));
    }


    default List<ShopCategory> selectListByIdsAndStatus(Collection<Long> ids, Integer status) {
        ids.removeIf(id -> id == null || id <= 0);
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return selectList(new CoreLambdaQueryWrapper<ShopCategory>()
                .inIfPresent(ShopCategory::getId, ids)
                .eq(ShopCategory::getStatus, status)
                .orderByDesc(ShopCategory::getRecommend)
                .orderByAsc(ShopCategory::getSort));
    }


    default ShopCategory selectOneByCodeAndStatus(String code, Integer status) {
        return selectOne(ShopCategory::getCode, code, ShopCategory::getStatus, status);
    }

    @Select("""
                    SELECT `value` as code,`label` AS name
                    FROM `system_dict_data`
                    WHERE `dict_type`='shop_category_code' AND `status` = 0 AND `deleted` = FALSE
                    ORDER BY `id` DESC
            """)
    List<ShopCategoryCodeBO> selectAllCode();

    default ShopCategory selectByCode(String code) {
        CoreLambdaQueryWrapper<ShopCategory> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.eqIfPresent(ShopCategory::getCode, code);
        wrapper.limitN(1);
        return selectOne(wrapper);
    }

    @Select("""
                    SELECT `parent_id` FROM `shop_category` WHERE `id` = #{id} AND `deleted` = FALSE
            """)
    Long selectParentIdById(@Param("id") Long id);

    default ShopCategory selectBySupplyRelatedId(Long supplyRelatedId) {
        return selectOne(ShopCategory::getSupplyRelatedId, supplyRelatedId);
    }

    default List<ShopCategory> selectSonsBySupplyRelatedId(Long supplyRelatedId) {
        return selectList(ShopCategory::getSupplyRelatedParentId, supplyRelatedId);
    }

    default List<ShopCategory> selectBySupplyRelatedIds(Collection<Long> supplyRelatedIds) {
        supplyRelatedIds.removeIf(id -> id == null || id <= 0);
        return selectList(new CoreLambdaQueryWrapper<ShopCategory>()
                .in(ShopCategory::getSupplyRelatedId, supplyRelatedIds));
    }

}
